﻿using Abp.Domain.Entities;
using GN.Pay.Core.Exceptions;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GN.Pay.Core.Entities
{
    //交易账簿
    [Table("Trade_AccountBook")]
    [Serializable]
    public class TradeAccountBook : Entity<long>
    {
        /// <summary>
        /// 应用Id
        /// </summary>
        [Required]
        [StringLength(maximumLength: 36)]
        public string AppId { get; set; }

        /// <summary>
        /// 申请号
        /// </summary>
        [StringLength(maximumLength: 36)]
        public string ApplyId { get; set; }

        /// <summary>
        /// 订单号
        /// </summary>
        [Required]
        [StringLength(maximumLength: 32)]
        public string OrderNo { get; set; }

        //订单时间
        public DateTime OrderTime { get; set; }

        //订单金额
        public decimal OrderMoney { get; set; }

        /// <summary>
        /// 会员
        /// </summary>
        [StringLength(maximumLength: 64)]
        public string MemberNo { get; set; }

        //商品标题
        public string Subject { get; set; }

        //商品详情
        public string Body { get; set; }

        /// <summary>
        /// 订单备注
        /// </summary>
        public string Remark { get; set; }

        /// <summary>
        /// 应用Ip地址
        /// </summary>
        [Required]
        [StringLength(maximumLength: 255)]
        public string AppIp { get; set; }

        /// <summary>
        /// 首个付款通道
        /// </summary>
        [Required]
        [StringLength(maximumLength: 32)]
        public string FirstChannelId { get; set; }

        /// <summary>
        /// 付款时间
        /// </summary>
        public DateTime PayTime { get; set; }

        /// <summary>
        /// 付款次数
        /// </summary>
        [Range(0, int.MaxValue)]
        public int PayCount { get; set; }

        /// <summary>
        /// 付款费用
        /// </summary>
        [Range(0.00, double.MaxValue)]
        public decimal PayFee { get; set; }

        /// <summary>
        /// 付款金额
        /// </summary>
        [Range(0.01, double.MaxValue)]
        public decimal PayMoney { get; set; }

        /// <summary>
        /// 退款金额
        /// </summary>
        [Range(0.00, double.MaxValue)]
        public decimal RefundMoney { get; set; }

        /// <summary>
        /// 退款费用
        /// </summary>
        [Range(0.00, double.MaxValue)]
        public decimal RefundFee { get; set; }

        /// <summary>
        /// 帐簿时间
        /// </summary>
        public DateTime BookTime { get; set; }

        /// <summary>
        /// 交易状态
        /// </summary>
        public int TradeState { get; set; }

        /// <summary>
        /// 交易余额
        /// </summary>
        [Range(0.00, double.MaxValue)]
        public decimal TradeBalanceMoney { get; set; }

        /// <summary>
        /// 帐簿余额
        /// </summary>
        [Range(0.00, double.MaxValue)]
        public decimal BookBalanceMoney { get; set; }

        /// <summary>
        /// 应用
        /// </summary>
        public virtual MerchantAppInfo MerchantApp { get; set; }

        /// <summary>
        /// 交易账簿通道
        /// </summary>
        [ForeignKey("BookId")]
        public virtual ICollection<TradeAccountBookChannel> TradeAccountBookChannels { get; set; }

        /// <summary>
        /// 交易退款账簿
        /// </summary>
        [ForeignKey("BookId")]
        public virtual ICollection<TradeRefundBook> TradeRefundBooks { get; set; }

        /// <summary>
        /// 计算余额
        /// </summary>
        public void CalcBalanceMoney()
        {
            this.BookBalanceMoney = this.PayMoney - this.PayFee - this.RefundMoney - this.RefundFee;
            this.TradeBalanceMoney = this.PayMoney - this.RefundMoney;
            if (this.OrderMoney <= 0)
            {
                this.TradeState = Consts.ServiceConstant.BookTradeState.PayMoney_Unknown_Apply;
            }
            else if (this.PayMoney < this.OrderMoney)
            {
                this.TradeState = Consts.ServiceConstant.BookTradeState.PayMoney_LessThan_OrderMoney;
            }
            else if (this.PayMoney > this.OrderMoney)
            {
                this.TradeState = Consts.ServiceConstant.BookTradeState.PayMoney_GreaterThan_OrderMoney;
            }
            else
            {
                this.TradeState = Consts.ServiceConstant.BookTradeState.PayMoney_Equals_OrderMoney;
            }
        }

        /// <summary>
        /// 添加通道金额
        /// </summary>
        /// <param name="bookChannel"></param>
        public void AddChannelMoney(TradeAccountBookChannel bookChannel)
        {
            if (bookChannel == null)
            {
                throw new ArgumentNullException(nameof(bookChannel));
            }
            this.PayMoney += bookChannel.PayMoney;
            this.PayFee += bookChannel.PayFee;
            this.PayCount += 1;
            this.CalcBalanceMoney();
        }

        /// <summary>
        /// 添加退款金额
        /// </summary>
        /// <param name="refundBook"></param>
        public void AddRefundMoney(TradeRefundBook refundBook)
        {
            if (refundBook == null)
            {
                throw new ArgumentNullException(nameof(refundBook));
            }
            this.RefundFee += refundBook.RefundFee;
            this.RefundMoney += refundBook.RefundMoney;
            this.CalcBalanceMoney();
        }
        
    }
}
